package com.rd.sys.servlet.auth;

import java.io.BufferedReader;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

import com.rd.sys.common.base.CommonConstants;
import com.rd.sys.common.utils.crypto.BASE64;
import com.rd.sys.common.utils.crypto.TripleDES;
import com.rd.sys.common.web.session.SessionUtil;
import com.rd.sys.dto.commmon.base.EyeException;
import com.rd.sys.dto.commmon.base.EyeResult;
import com.rd.sys.dto.sys.user.UserInfoDto;
import com.rd.sys.dto.sys.user.UserLoginDto;
import com.rd.sys.dto.sys.user.UserSecurityDto;
import com.rd.sys.service.sys.user.UserAllInOneService;
import com.rd.sys.service.sys.user.UserLoginService;

public class SsoLoginServlet extends AuthBaseServlet {
    private static final long serialVersionUID = 4765194998051901202L;

    private UserAllInOneService userSecurityService = (UserAllInOneService) getService("userAllInOneServiceImpl");
    private UserLoginService userLoginService = (UserLoginService) getService("userLoginServiceImpl");

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        EyeResult result = null;
        try {

            /** 1. 从http请求中读取客户端发送的登录串 */
            BufferedReader reader = null;

            String rand_req = null;
            String content_req = null;
            try {
                // reader = new BufferedReader(new
                // InputStreamReader(req.getInputStream(),
                // CommonConstants.SysParamConstants.SYS_CHARSET));
                // rand_req = reader.readLine(); // 根据协议,第一行为随机码
                // content_req = reader.readLine();// 第二行是加密后的消息原文

                // 协议变更,采用http get方式
                rand_req = req.getParameter("code");
                content_req = req.getParameter("param");

            } catch (Exception ex) {
                logger.error("", ex);
                throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_READ_REQUEST_ERROR);
            } finally {
                // if (reader != null) {
                // reader.close();
                // }
            }

            /** 2. 从Session中取出用户编码和随机码 (为兼容客户端现从缓存中获取) */
            // String login_session = (String)
            // SessionUtil.getSession(req).getAttribute(
            // CommonConstants.UserConstats.AUTH_LOGIN_SESSION_FLAG);
            // SessionUtil.getSession(req).removeAttribute(CommonConstants.UserConstats.AUTH_LOGIN_SESSION_FLAG);
            // // 取出后立即清除
            // String usercode_session =
            // login_session.split(CommonConstants.UserConstats.AUTH_SPLIT_SIGN)[0];
            // String rand_session =
            // login_session.split(CommonConstants.UserConstats.AUTH_SPLIT_SIGN)[1];
            String usercode_session = this.queryLoginCode(rand_req);
            String rand_session = rand_req;
            if (StringUtils.isBlank(rand_session) || StringUtils.isBlank(usercode_session)) {
                // 未从缓存中获取到值
                throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_FAIL_RAND_NOT_EXIST);
            }

            /** 3. 将登录串解密分解 */
            String userCode = null;
            String rand = null;
            String projectCode = null;
            String schemeCode = null;
            String resultCode = null;
            boolean redictIndex = true; // 鉴权通过重定向首页

            UserSecurityDto userSecurity = null;
            UserInfoDto userInfo = new UserInfoDto();
            try {
                userInfo.setUsercode(usercode_session);
                userSecurity = userSecurityService.selectUserSecurityInfo(userInfo);
                if (userSecurity == null) {
                    throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_FAIL_USER_NOT_EXIST);
                }
            } catch (Exception ex) {
                logger.error("", ex);
                throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_FAIL_USER_NOT_EXIST);
            }

            /** 4. 按协议解析登录信息 */
            try {
                String baseKey = BASE64.decode2String(userSecurity.getBasekey());// 根据安全配置信息中基础密钥解密
                content_req = TripleDES.decrypt2String(baseKey, BASE64.decode(content_req));
            } catch (Exception ex) {
                logger.error("", ex);
                throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_FAIL_PROTOCOL_ERROR);
            }
            String[] deLoginCodes = content_req.split(CommonConstants.UserConstats.AUTH_SPLIT_SIGN);
            if (deLoginCodes.length == 2) {
                userCode = deLoginCodes[0];
                rand = deLoginCodes[1];
            } else if (deLoginCodes.length == 4) {
                userCode = deLoginCodes[0];
                rand = deLoginCodes[1];
                projectCode = deLoginCodes[2];
                schemeCode = deLoginCodes[3];
            } else if (deLoginCodes.length == 5) {
                userCode = deLoginCodes[0];
                rand = deLoginCodes[1];
                projectCode = deLoginCodes[2];
                schemeCode = deLoginCodes[3];
                resultCode = deLoginCodes[4];
            } else {
                throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_FAIL_PROTOCOL_ERROR);
            }

            /** 5. 登录鉴权 */

            // 随机码是否一致
            if (StringUtils.isBlank(rand_session) || StringUtils.isBlank(rand) || !rand_session.equals(rand)) {
                throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_FAIL_RAND_IDENTICAL);
            }
            // 用户是否一致(查询用户安全配置信息时,已校验了用户的存在性)
            if (StringUtils.isBlank(usercode_session) || StringUtils.isBlank(userCode)
                    || !usercode_session.equals(userCode)) {
                throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_FAIL_USER_IDENTICAL);
            }
            // 项目和方案存在性
//            if (StringUtils.isNotBlank(projectCode) && StringUtils.isNotBlank(schemeCode)) {
//                if (!isSchemeExist(userCode, projectCode, schemeCode)) {
//                    throw new EyeException(EyeResult.ResultDefine.AUTH_LOGIN_PROJECT_SCHEME_NOTFIND);
//                } else {
//                    redictIndex = false; // 若存在,则重定向到方案分析页
//                }
//            }

            /** 6. 鉴权通过,登录并设置Session */
            UserLoginDto loginInfo = new UserLoginDto();
            loginInfo.setUsercode(usercode_session);
            userInfo = userLoginService.loginPortalByAuth(loginInfo);
            SessionUtil.createSession(req, CommonConstants.UserConstats.USER_SESSION_FLAG, userInfo);

            /** 7. 鉴权通过,重定向 */
            String redirectUrl = "http://" + req.getHeader("Host") + req.getContextPath();
            if (redictIndex) {
                redirectUrl += analysisIndexUrl + "?theSource=" + CommonConstants.UserConstats.USER_THE_CLIENT_SOURCE;
            } else {
                redirectUrl += analysisSchemeUrl + "?theSource=" + CommonConstants.UserConstats.USER_THE_CLIENT_SOURCE
                        + "&projectCode=" + projectCode + "&schemeCode=" + schemeCode;
                if (resultCode != null) { // 若传递结果编码,则也带到分析页面中
                    redirectUrl += "&resultCode=" + resultCode;
                }
            }

            /** 7. 先响应结果码,再执行重定向 */
            result = new EyeResult(EyeResult.ResultDefine.COMMON_SUCCESS);
            sendResponse(result, req, resp);

            resp.sendRedirect(redirectUrl);

        } catch (EyeException ex) {
            result = new EyeResult(ex.getResult());
            sendResponse(result, req, resp);
        } catch (Exception ex) {
            logger.error("", ex);
            result = new EyeResult(EyeResult.ResultDefine.AUTH_LOGIN_FAIL);
            sendResponse(result, req, resp);
        }
    }
}
